package net.joyphper.commons.security;

import java.security.SecureRandom;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.joyphper.enums.UserStatus;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class Interceptor extends HandlerInterceptorAdapter {
	private final Logger logger = Logger.getLogger(getClass());
	
	@Autowired
	private SecurityUtil securityUtil;
	
	private String[] passUrl; //直接通过的url
	private String primaryDomain;
	private boolean requestLog;
	
	private String version;
	
	
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		
		/*------------------产生会话ID--------------------------*/
		String sid = SidCookie.getSidCookie(request);
		if(null == sid || "".equals(sid)){
			sid = SidCookie.setSidCookie(response,primaryDomain);
			logger.debug("产生新的SID："+sid);
	    }
		
		String requestUri = request.getRequestURI().replace(request.getContextPath(), ""); // 不带ContextPath
		
		Auth auth = this.securityUtil.getAuth();
		
		//把用户的信息存到request的请求中，一保证一次请求只去读取一次用户信息
		request.setAttribute("__auth", auth);
		
		/*------------------访问日志打印--------------------------*/
		if(this.requestLog){
			try {
				String requestType = request.getMethod();
				String ip = request.getRemoteAddr();
				String agent = request.getHeader("User-Agent");
				Map<String,String> map = new HashMap<String,String>();
				Enumeration<String> paramNames = request.getParameterNames();
				while (paramNames.hasMoreElements()) {
					String paramName = (String) paramNames.nextElement();
					String[] paramValues = request.getParameterValues(paramName);
					if (paramValues.length == 1) {
						String paramValue = paramValues[0];
						if (paramValue.length() != 0) {
							map.put(paramName, paramValue);
						}
					}
				}
				logger.info(auth.getLoginName()+";" + requestUri + ";" + requestType + "; "+map+";"+ip+";{"+agent+"}");
			} catch (Exception e) {
				logger.error("日志异常",e);
			}
		}
		
		//可能直接访问有URL列表
		if(this.passUrl!=null && this.passUrl.length>0){
			for(int i=0;i<this.passUrl.length;i++){
				if(requestUri.matches(this.passUrl[i]) ){
					return true;
				}
			}
		}
		
		Set<String> resources = auth.getResources();
		// 验证用户权限
		boolean pass = false;
		if(resources!=null && resources.size()>0){
			for(String res : resources){
				if(requestUri.matches(res)){ //利用正则表达试去进行匹配权限
					pass=true;
					break ;
				}
			}
		}
		
		if(auth == null || auth.getId()==null || !pass || !UserStatus.OK.equals(auth.getStatus())){
			response.sendError(HttpServletResponse.SC_FORBIDDEN); //返回403状态，接下就是系统对403的处理了
			return false;
		}
		return true;
	}

	@Override
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex) {
	}

	@Override
	public void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		Random random = new SecureRandom();
		request.setAttribute("__random", random.nextInt());
		request.setAttribute("__version", this.version);
	}

	public void setPassUrl(String[] passUrl) {
		this.passUrl = passUrl;
	}

	public void setPrimaryDomain(String primaryDomain) {
		this.primaryDomain = primaryDomain;
	}

	public void setRequestLog(boolean requestLog) {
		this.requestLog = requestLog;
	}
	public void setVersion(String version) {
		this.version = version;
	}
}
